package dbexp.utils;

import java.util.Arrays;
import java.util.List;

public class ObjectUtil {

	/**
	 * Przeksztalca liste obiektow na tablice obiektow
	 * @return tablica obiektow
	 */
	public static Object[] getArray(List<?> in){
		return getArray( in , false);
	}
	
	/**
	 * Przeksztalca liste obiektow na tablice obiektow
	 *
	 * @param in lista obiektow
	 * @param sort czy sortowac elementy
	 *
	 * @return tablica obiektow
	 */
	public static Object[] getArray(List<?> in, boolean sort){
		Object[] out = null;
		if(in!=null){
			if(in.size()>0){
				out = in.toArray();
				if(sort){
					Arrays.sort(out);
				}
			}else{
				out = new Object[0];
			}
		}
		return out;
	}

	/**
	 * Przeksztalca liste ciagow znakowych na tablice ciagow znakowych
	 *
	 * @param in lista ciagow znakowych
	 * @param sort czy sortowac elementy
	 * @param tools narzedzie
	 *
	 * @return tablica ciagow znakowych
	 * @see parasoft.centrap.utils.Tool
	 */
	public static Object[] getArray(List<?> in, boolean sort, Tool tools){
		if(tools != null){
			return getArray( in,  sort, new Tool[]{ tools });
		}else{
			return getArray( in,  sort, new Tool[0]);
		}
	}
	/**
	 * Przeksztalca liste obiektow na tablice obiektow
	 *
	 * @param in lista obiektow
	 * @param tools narzedzie
	 *
	 * @return tablica obiektor
	 * @see parasoft.centrap.utils.Tool
	 */
	public static Object[] getArray(List<?> in, Tool tools){
		if(tools != null){
			return getArray( in , false ,new Tool[]{tools});
		}else{
			return getArray( in , false ,new Tool[0]);
		}
	}
	/**
	 * Przeksztalca liste obiektow na tablice obiektow
	 *
	 * @param in lista obiektow
	 * @param tools tablica narzedzi
	 *
	 * @return tablica obiektow
	 * @see parasoft.centrap.utils.Tool
	 */
	public static Object[] getArray(List<?> in, Tool[] tools){
		return getArray( in , false ,tools);
	}
	/**
	 * Przeksztalca liste obiektow na tablice obiektow.</br>
	 * Przy sortowaniu wymagana implementacja equals oraz compareTo.
	 *
	 * @param in lista obiektow
	 * @param tools narzedzie
	 * @param sort czy sortowac elementy
	 *
	 * @return tablica obiektow
	 * @see parasoft.centrap.utils.Tool
	 * @see java.lang.Comparable
	 */
	public static Object[] getArray(List<?> in, Tool tools , boolean sort){
		if(tools != null){
			return  getArray( in, new Tool[]{ tools }, sort);
		}else{
			return  getArray( in, new Tool[0] , sort);
		}
	}
	/**
	 * Przeksztalca liste obiektow na tablice obiektow.</br>
	 * Przy sortowaniu wymagana implementacja equals oraz compareTo.
	 *
	 * @param in lista obiektow
	 * @param sort czy sortowac elementy
	 * @param tools tablica narzedzi
	 *
	 * @return tablica obiektow
	 * @see parasoft.centrap.utils.Tool
	 * @see java.lang.Comparable
	 */
	public static Object[] getArray(List<?> in, boolean sort, Tool[] tools){
		Object[] out = null;
		if(in!=null){
			if(in.size()>0){
				out = new Object[in.size()];
				in.toArray(out);
				if(sort){
					Arrays.sort(out);
				}
				for(int i =0 ;i <out.length; i++){
					out[i] = (invoke(out[i],tools, new Integer(i)));
				}
			}else{
				out = new Object[0];
			}
		}
		return out;
	}
	/**
	 * Przeksztalca liste obiektow na tablice obiektow.</br>
	 * Przy sortowaniu wymagana implementacja equals oraz compareTo.
	 * @param in lista obiektow
	 * @param tools tablica narzedzi
	 * @param sort czy sortowac elementy
	 *
	 * @return tablica obiektow
	 * @see parasoft.centrap.utils.Tool
	 * @see java.lang.Comparable
	 */
	protected static Object[] getArray(List<?> in, Tool[] tools , boolean sort){
		Object[] out = new Object[in.size()];
		if(in!=null && in.size()>0){
			boolean comparable = false;
			for(int i =0 ;i <in.size(); i++){
				Object cout = (invoke(in.get(i),tools, new Integer(i))); 
				if(sort){
					Class<?>[] interfaces = cout.getClass().getInterfaces();
					for (int j = 0; j < interfaces.length; j++) {
						if(interfaces[j]==Comparable.class){
							comparable=true;
						}
					}
				}
				out[i] = cout;
			}
			if(sort && comparable){
				Arrays.sort(out);
			}
		}
		return out;
	}
	/**
	 * Przetwarza obiekt in zgodnie z narzedziami podanymi w tablicy tools.<br />
	 * Numer elementu ustawiony na 0
	 *
	 * @param in obiekt wejsciowy
	 * @param tools narzedzie
	 *
	 * @return przetworzony obiekt
	 * @see parasoft.centrap.utils.Tool
	 * @see parasoft.centrap.utils.ObjectUtil#invoke(Object, Tool, int)
	 */
	public static Object invoke(Object in, Tool tools){
		return invoke(in, tools, 0);
	}

	/**
	 * Przetwarza obiekt in zgodnie z narzedziami podanymi w tablicy tools.<br />
	 * Numer elementu ustawiony na 0
	 *
	 * @param in obiekt wejsciowy
	 * @param tools tablica narzedzi
	 *
	 * @return przetworzony obiekt
	 * @see parasoft.centrap.utils.Tool
	 */
	public static Object invoke(Object in, Tool[] tools){
		return invoke(in, tools, new Integer(0));
	}

	/**
	 * Przetwarza obiekt in zgodnie z narzedziami podanymi w tablicy tools.<br />
	 * Mozliwosc ustawienia numeru elementu
	 *
	 * @param in obiekt wejsciowy
	 * @param tools narzedzie
	 * @param x numer elementu
	 *
	 * @return przetworzony obiekt
	 * @see parasoft.centrap.utils.Tool
	 */
	public static Object invoke(Object in, Tool tools, int x){
		return invoke(in, tools, new Integer(x));
	}

	/**
	 * Przetwarza obiekt in zgodnie z narzedziami podanymi w tablicy tools.<br />
	 * Mozliwosc ustawienia numeru elementu
	 *
	 * @param in obiekt wejsciowy
	 * @param tools tablica narzedzi
	 * @param x numer elementu
	 *
	 * @return przetworzony obiekt
	 * @see parasoft.centrap.utils.Tool
	 */
	public static Object invoke(Object in, Tool[] tools, int x){
		return invoke(in, tools, new Integer(x));
	}

	/**
	 * Przetwarza obiekt in zgodnie z narzedziami podanymi w tablicy tools.<br />
	 * Mozliwosc ustawienia numeru elementu
	 *
	 * @param in obiekt wejsciowy
	 * @param tools narzedzie
	 * @param x numer elementu
	 *
	 * @return przetworzony obiekt
	 * @see parasoft.centrap.utils.Tool
	 */
	protected static Object invoke(Object in, Tool tools, Integer x){
		return invoke(in, new Tool[]{tools}, x);
	}

	/**
	 * Przetwarza obiekt in zgodnie z narzedziami podanymi w tablicy tools.<br />
	 * Mozliwosc ustawienia numeru elementu
	 *
	 * @param in obiekt wejsciowy
	 * @param tools tablica narzedzi
	 * @param x numer elementu
	 *
	 * @return przetworzony obiekt
	 * @see parasoft.centrap.utils.Tool
	 */
	protected static Object invoke(Object in, Tool[] tools, Integer x){
		Object out = in;
		if(in!=null && tools != null && tools.length > 0){
			for(int i = 0 ;i < tools.length;i++){
				if(tools[i]==null){
					continue;
				}
				tools[i].setNr(x);
				out = tools[i].invoke(out);
			}
		}
		return out;
	}
}

